commonlibsse_ng\re\n/
NiTransform.rs1use crate::re::NiMatrix3::NiMatrix3;
2use crate::re::NiPoint3::NiPoint3;
3
4#[repr(C)]
6#[derive(Debug, Clone, Copy, PartialEq)]
7pub struct NiTransform {
8 pub rotate: NiMatrix3,
9 pub translate: NiPoint3,
10 pub scale: f32,
11}
12
13impl NiTransform {
14 #[inline]
16 pub const fn new() -> Self {
17 Self { rotate: NiMatrix3::new(), translate: NiPoint3::zero(), scale: 1.0 }
18 }
19
20 pub fn invert(&self) -> Self {
22 let inv_scale = 1.0 / self.scale;
23 let inv_rotate = self.rotate.transpose();
24 let inv_translate = (inv_rotate * -self.translate) * inv_scale;
25
26 Self { rotate: inv_rotate, translate: inv_translate, scale: inv_scale }
27 }
28
29 #[inline]
31 pub fn mul_transform(&self, rhs: &Self) -> Self {
32 Self {
33 scale: self.scale * rhs.scale,
34 rotate: self.rotate * rhs.rotate,
35 translate: self.translate + (self.rotate * rhs.translate) * self.scale,
36 }
37 }
38
39 #[inline]
41 pub fn mul_point(&self, point: &NiPoint3) -> NiPoint3 {
42 ((self.rotate * *point) * self.scale) + self.translate
43 }
44}
45
46impl Default for NiTransform {
47 #[inline]
48 fn default() -> Self {
49 Self::new()
50 }
51}
52
53impl core::ops::Mul for NiTransform {
54 type Output = Self;
55
56 #[inline]
57 fn mul(self, rhs: Self) -> Self::Output {
58 self.mul_transform(&rhs)
59 }
60}
61
62impl core::ops::Mul<NiPoint3> for NiTransform {
63 type Output = NiPoint3;
64
65 #[inline]
66 fn mul(self, rhs: NiPoint3) -> Self::Output {
67 self.mul_point(&rhs)
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_invert_transform() {
77 let transform = NiTransform {
78 rotate: NiMatrix3::new(),
79 translate: NiPoint3::new(1.0, 2.0, 3.0),
80 scale: 2.0,
81 };
82
83 let inverted = transform.invert();
84 let expected = NiTransform {
85 rotate: NiMatrix3 { entry: [[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]] },
86 translate: NiPoint3 { x: -0.5, y: -1.0, z: -1.5 },
87 scale: 0.5,
88 };
89 assert_eq!(inverted, expected);
90 }
91
92 #[test]
93 fn test_mul_transform() {
94 let t1 = NiTransform {
95 rotate: NiMatrix3::new(),
96 translate: NiPoint3::new(1.0, 2.0, 3.0),
97 scale: 2.0,
98 };
99
100 let t2 = NiTransform {
101 rotate: NiMatrix3::new(),
102 translate: NiPoint3::new(4.0, 5.0, 6.0),
103 scale: 3.0,
104 };
105
106 let result = t1 * t2;
107 let expected = NiTransform {
108 rotate: NiMatrix3::new(),
109 translate: NiPoint3::new(9.0, 12.0, 15.0),
110 scale: 6.0,
111 };
112
113 assert_eq!(result, expected);
114 }
115
116 #[test]
117 fn test_mul_point() {
118 let transform = NiTransform {
119 rotate: NiMatrix3::new(),
120 translate: NiPoint3::new(1.0, 2.0, 3.0),
121 scale: 2.0,
122 };
123
124 let point = NiPoint3::new(1.0, 1.0, 1.0);
125 let result = transform * point;
126 assert_eq!(result, NiPoint3::new(3.0, 4.0, 5.0));
127 }
128}